﻿using System;
using Aeon.Framework;
using Aeon.Framework.Audio;
using System.Windows.Forms;
using Aeon.Testing.Properties;

namespace Aeon.Testing.Sounds
{

public partial class WindowDemoSnd : Form
    {
    // --- Fields:
    
    private World scene;            // Scene graphics handler.
    private Boolean playing;        // Play button flag.
    private Boolean paused;         // Paused flag.

    private IAudio effect;          // Sound effect.
    private IAudio background;      // Background sound.
    
    #region Content
    
    private static String path = Application.StartupPath+@"\Demos\Content\";
    
    private String soundWav = path+"Example.wav";
    private String soundOgg = path+"Example.ogg";
    
    #endregion
    
    // --- Constructor:

    public WindowDemoSnd()
        {
        InitializeComponent();
        Icon = Resources.AeonIco;
        
        // Prepare window:
        
        playing = false;
        paused = false;
        buttonStates();
        
        // Prepare GL:
        
        Display.InitializeContexts();
        
        startWorld();        
        
        Display.Paint += RenderHandler;
        Display.PreviewKeyDown += KeyHandler;
        }

    // --- Internal Methods:
    
    /// <summary>
    /// Initializes and prepares world.
    /// 
    /// </summary>
    private void startWorld()
        {
        // Create world:
        
        WorldManager.SetModules(typeof(MockTextureManager),typeof(MockFontManager),typeof(AeonAudioManager),typeof(MockInputManager),typeof(MockPhysicsManager));
        
        scene = WorldManager.CreateWorld("Test World");
        scene.SetCamera(Display.Height,Display.Width);
        scene.CameraMoveTo(new Position(0,0,500));
        scene.CameraTurnTo(new Framework.Orientation(-40,0,0));
        
        // Set scene:
        
        AeonColor ambU = new AeonColor(0.2f,0.2f,0.2f,1.0f);
        AeonColor difU = new AeonColor(0.8f,0.8f,0.8f,1.0f);
        AeonColor spcU = new AeonColor(0.5f,0.5f,0.5f,1.0f);
        Position posU = new Position(0.0f,100.0f,0.0f);

        AeonLight light = new AeonLight("MainLight",posU,ambU,difU,spcU);
        scene.Add(light);

        // Audio objects:

        AudioMode bgMode = new AudioMode();
        bgMode.Relative = true;
        bgMode.Loop = true;

        background = new AeonAudio(soundOgg,0.5f,bgMode);
        effect = new AeonAudio(soundWav,1);
        }
    
    /// <summary>
    /// Ends world.
    /// 
    /// </summary>
    private void endWorld()
        {
        scene.DestroyScene();

        Display.DestroyContexts();        
        }

    /// <summary>
    /// Mantains possible action states.
    /// 
    /// </summary>
    private void buttonStates()
        {
        ButtonStop.Enabled = playing;
        
        if (playing)
            {
            ButtonPlay.Text = ";";
            toolTips.SetToolTip(ButtonPlay,"Pause");
            }

        else {
             ButtonPlay.Text = "4";
             toolTips.SetToolTip(ButtonPlay,"Play");
             }
        }

    /// <summary>
    /// Plays audio.
    /// Start or resume.
    /// 
    /// </summary>
    private void play()
        {
        if (paused) { scene.AudioManager.Pause(background); }
        else { scene.AudioManager.Play(background); }
        
        playing = true;
        paused = false;
        buttonStates();
        }

    /// <summary>
    /// Pauses audio.
    /// 
    /// </summary>
    private void pause()
        {
        scene.AudioManager.Pause(background);

        playing = false;
        paused = true;
        buttonStates();
        }

    /// <summary>
    /// Stops audio.
    /// 
    /// </summary>
    private void rewind()
        {
        scene.AudioManager.Stop(background);

        playing = false;
        buttonStates();
        }

    /// <summary>
    /// Plays audio.
    /// 
    /// </summary>
    private void quick()
        {

        scene.AudioManager.Play(effect);
        }

    // --- Component Event Handlers:
    
    /// <summary>
    /// Frees resources and really closes window.
    /// Also captures the red X button.
    /// 
    /// </summary>
    private void WindowDemoSnd_FormClosing(object sender,FormClosingEventArgs e)
        {
        
        endWorld();
        }
    
    /// <summary>
    /// Closes window.
    /// 
    /// </summary>
    private void ButtonExit_Click(object sender,EventArgs e)
        {
        
        this.Close();
        }
    
    /// <summary>
    /// Handler for button Click.
    /// Plays or pauses the sound.
    /// 
    /// </summary>
    private void ButtonPlay_Click(object sender, EventArgs e)
        {
        if (!playing) { play(); }
        else { pause(); }
        }

    /// <summary>
    /// Handler for button Click.
    /// Stops the sound.
    /// 
    /// </summary>
    private void ButtonStop_Click(object sender, EventArgs e)
        {
        
        rewind();
        }

    /// <summary>
    /// Handler for button click.
    /// Plays a quick sound.
    /// 
    /// </summary>
    private void ButtonFx_Click(object sender, EventArgs e)
        {

        quick();
        }

    // --- OpenGL Component Event Handlers:

    /// <summary>
    /// Handler for the OnPaint event.
    /// 
    /// </summary>    
    public void RenderHandler(Object obj, PaintEventArgs arg)
        {
        
        scene.RenderScene();
        }

    /// <summary>
    /// Handler for KeyPress event.
    /// Key redundancy for button actions.
    /// 
    /// </summary>
    private void KeyHandler(Object sender, PreviewKeyDownEventArgs arg)
        {
        switch(arg.KeyCode)
            {                                                           // Sound Control:            
            
            case Keys.S: rewind(); break;                               // Stop
            case Keys.P: if (!playing) play(); else pause(); break;     // Play/Pause
            }

        // Prevents arrows from losing focus
        arg.IsInputKey = true;
        }

    }


}
